package com.zbkj.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.idev.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.zbkj.admin.constants.BalanceRecordConstants;
import com.zbkj.admin.constants.Constants;
import com.zbkj.admin.dao.EbDividendArraignMpMapper;
import com.zbkj.admin.exception.CrmebException;
import com.zbkj.admin.mapper1.EbDividendArraignMaper;
import com.zbkj.admin.model.admin.SystemAdmin;
import com.zbkj.admin.model.cdkey.CardSecret;
import com.zbkj.admin.model.coupon.CouponUser;
import com.zbkj.admin.model.merchant.Merchant;
import com.zbkj.admin.model.order.Order;
import com.zbkj.admin.model.user.User;
import com.zbkj.admin.model.user.UserBalanceRecord;
import com.zbkj.admin.model.user.UserBankAccount;
import com.zbkj.admin.page.CommonPage;
import com.zbkj.admin.pojo.EbDividendArraignEntity;
import com.zbkj.admin.request.ArraignApplyRequest;
import com.zbkj.admin.request.PageParamRequest;
import com.zbkj.admin.response.EbDividendArraignResponse;
import com.zbkj.admin.result.CommonResultCode;
import com.zbkj.admin.service.*;
import com.zbkj.admin.util.SecurityUtil;
import com.zbkj.admin.vo.ArraignExcelVo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.result.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 积分管理
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class EbDividendArraignServiceImpl extends ServiceImpl<EbDividendArraignMaper, EbDividendArraignEntity> implements EbDividendArraignService {

    @Autowired
    private EbDividendArraignMpMapper ebDividendArraignMpMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private UserBankAccountService userBankAccountService;
    @Autowired
    private UserBalanceRecordService userBalanceRecordService;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private EbDividendConfigService ebDividendConfigService;

    /**
     * 分红审批记录
     *
     * @param page      分页数据
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 分页后数据
     */
    @Override
    public R<PageInfo<EbDividendArraignResponse>> page(Page<EbDividendArraignEntity> page, String examineAndApproveState, LocalDateTime startDate, LocalDateTime endDate) {
        PageInfo<EbDividendArraignEntity> objectPageInfo = PageHelper.startPage(page.getPageNum(), page.getPageSize())
                .doSelectPageInfo(() -> list(from().gt(EbDividendArraignEntity::getCreatedTime, startDate, ObjUtil::isNotEmpty)
                        .lt(EbDividendArraignEntity::getCreatedTime, endDate, ObjUtil::isNotEmpty)
                        .eq(EbDividendArraignEntity::getExamineAndApproveState, examineAndApproveState, ObjUtil::isNotEmpty)
                        .orderBy(EbDividendArraignEntity::getCreatedTime, Boolean.FALSE)));

        // 获取结果列表
        List<EbDividendArraignEntity> arraignList = objectPageInfo.getList();
        // 查询用户信息
        List<Integer> userIdList = arraignList.stream().map(EbDividendArraignEntity::getUId).distinct().collect(Collectors.toList());
        Map<Integer, User> userMap = userService.getUidMapList(userIdList);
        // 生成返回对象列表
        ArrayList<EbDividendArraignResponse> ebDividendArraignResponseList = new ArrayList<>();
        for(EbDividendArraignEntity arraign : arraignList){
            EbDividendArraignResponse ebDividendArraignResponse = new EbDividendArraignResponse();
            BeanUtil.copyProperties(arraign, ebDividendArraignResponse);
            if (userMap.containsKey(arraign.getUId())) {
                ebDividendArraignResponse.setUsername(userMap.get(arraign.getUId()).getIdentityName());
            }
            ebDividendArraignResponseList.add(ebDividendArraignResponse);
        }
        // 拼接返回数据
        PageInfo<EbDividendArraignResponse> returnPage = new PageInfo<>(ebDividendArraignResponseList);
        returnPage.setPageNum(page.getPageNum());
        returnPage.setPageSize(page.getPageSize());
        returnPage.setTotal(objectPageInfo.getTotal());
        returnPage.setPages(objectPageInfo.getPages());
        return R.success(returnPage);
    }

    /**
     * 审批提现记录
     *
     * @param id      主键id
     * @param status  审批数据状态
     * @param remarks 备注
     * @return 是否通过
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Boolean> toExamine(Long id, Integer status, String remarks) {
        updateById(EbDividendArraignEntity.builder().id(id).examineAndApproveState(status).arraignTime(LocalDateTime.now())
                .remarks(remarks).build());
        return null;
    }
    /**
     * 发起提现申请
     * */
    @Override
    @Transactional
    public Boolean submitArraignApply(ArraignApplyRequest request) {
        // 判断数据是否正确
        if(request.getAmountOfMoney() == null || request.getAmountOfMoney().compareTo(BigDecimal.ZERO) <= 0){
            log.error("提现金额不可为0");
        }

        // 获取提现银行卡信息
        UserBankAccount userBankAccount = new UserBankAccount();
        // 判断是否存在银行卡账号id
        if(request.getUserBankid() != null){
            // 用户选择了银行卡账号id 根据id查询银行卡信息
            userBankAccount = userBankAccountService.getById(request.getUserBankid());
        }else{
            // 用户未选择银行卡账号id 查询银行卡信息默认
            userBankAccount = userBankAccountService.getDefault();
        }

        // 判断数据是否正确
        if(userBankAccount == null || userBankAccount.getId() == null){
            log.error("未找到银行卡信息");
        }
        // 查询手续费率 计算实际到账金额、手续费
        BigDecimal handFee = ebDividendConfigService.getHandFee().divide(new BigDecimal(100));
        BigDecimal kickback = request.getAmountOfMoney().multiply(handFee);
        BigDecimal amountReceived = request.getAmountOfMoney().subtract(kickback);
        // 拼接保存数据
        EbDividendArraignEntity ebDividendArraignEntity = new EbDividendArraignEntity();
        // 根据申请类型（1：用户；2：商户） 判断保存数据
        if("1".equals(request.getType())){
            ebDividendArraignEntity.setUId(userService.getUserIdException());
        }else if("2".equals(request.getType())){
            // 获取商户信息
            SystemAdmin admin = SecurityUtil.getLoginUserVo().getUser();
            // 赋值参数
            ebDividendArraignEntity.setMerId(admin.getMerId());
        }else{
            log.error("申请类型不规范");
        }
        ebDividendArraignEntity.setExamineAndApproveState(0);
        ebDividendArraignEntity.setAmountOfMoney(request.getAmountOfMoney()); //
        ebDividendArraignEntity.setAmountReceived(amountReceived); // 实际到账金额
        ebDividendArraignEntity.setKickback(kickback); // 手续费
        ebDividendArraignEntity.setType(userBankAccount.getType());
        ebDividendArraignEntity.setBankName(userBankAccount.getBankName());
        ebDividendArraignEntity.setBankCode(userBankAccount.getBankCode());
        ebDividendArraignEntity.setCreatedTime(LocalDateTime.now());

        boolean bool = save(ebDividendArraignEntity);
        if(!bool){
            log.error("提现审核发起失败，uid = {}", ebDividendArraignEntity.getUId());
            throw new RuntimeException();
        }
        // 修改用户资金
        bool = userService.updateNowMoney(ebDividendArraignEntity.getUId(), ebDividendArraignEntity.getAmountOfMoney(), "sub");
        if(!bool){
            log.error("修改用户余额失败，uid = {}", ebDividendArraignEntity.getUId());
            throw new RuntimeException();
        }
        // 查询用户信息
        User user = userService.getById(ebDividendArraignEntity.getUId());
        // 添加资金流水
        UserBalanceRecord balanceRecord = new UserBalanceRecord();
        balanceRecord.setUid(ebDividendArraignEntity.getUId());
        balanceRecord.setAmount(ebDividendArraignEntity.getAmountOfMoney());
        balanceRecord.setLinkId("0");
        balanceRecord.setLinkType(BalanceRecordConstants.BALANCE_RECORD_LINK_TYPE_SYSTEM);
        balanceRecord.setType(BalanceRecordConstants.BALANCE_RECORD_TYPE_SUB);
        balanceRecord.setBalance(user.getNowMoney());
        balanceRecord.setRemark(BalanceRecordConstants.BALANCE_RECORD_REMARK_Arraign);
        userBalanceRecordService.save(balanceRecord);
        if(!bool){
            log.error("增加资金流水失败，uid = {}", ebDividendArraignEntity.getUId());
            throw new RuntimeException();
        }
        return Boolean.TRUE;
    }

    /**
     * 查询用户提现记录
     * */
    @Override
    public PageInfo<EbDividendArraignEntity> getUserArraignApplyList(PageParamRequest request){
        PageInfo<EbDividendArraignEntity> pageInfo = PageHelper.startPage(request.getPage(), request.getLimit())
                .doSelectPageInfo(() -> list(from().eq(EbDividendArraignEntity::getUId, userService.getUserIdException(), ObjUtil::isNotEmpty)
                        .orderBy("created_time", false)));
        return pageInfo;
    }

    /**
     * 订单导出
     */
    @Override
    public List<ArraignExcelVo> exportArraign(String examineAndApproveState, LocalDateTime startDate, LocalDateTime endDate) {
        LambdaQueryWrapper<EbDividendArraignEntity> lqw = Wrappers.lambdaQuery();
        // 拼接查询展示数据
        lqw.select(EbDividendArraignEntity::getExamineAndApproveState,EbDividendArraignEntity::getAmountOfMoney,EbDividendArraignEntity::getType,
                EbDividendArraignEntity::getBankName,EbDividendArraignEntity::getBankCode,EbDividendArraignEntity::getCreatedTime,EbDividendArraignEntity::getArraignTime,
                EbDividendArraignEntity::getCreatedBy,EbDividendArraignEntity::getRemarks,EbDividendArraignEntity::getUId,EbDividendArraignEntity::getAmountReceived);
        // 拼接查询条件
        if (StrUtil.isNotBlank(examineAndApproveState)) {
            lqw.eq(EbDividendArraignEntity::getExamineAndApproveState, examineAndApproveState);
        }
        if (startDate != null) {
            lqw.gt(EbDividendArraignEntity::getCreatedTime, startDate);
        }
        if (startDate != null) {
            lqw.lt(EbDividendArraignEntity::getCreatedTime, endDate);
        }
        lqw.orderByDesc(EbDividendArraignEntity::getCreatedTime);

        List<EbDividendArraignEntity> arraignList = ebDividendArraignMpMapper.selectList(lqw);
        if (CollUtil.isEmpty(arraignList)) {
            throw new CrmebException(CommonResultCode.VALIDATE_FAILED, "没有可导出的数据！");
        }
        // 查询用户信息
        List<Integer> userIdList = arraignList.stream().map(EbDividendArraignEntity::getUId).distinct().collect(Collectors.toList());
        Map<Integer, User> userMap = userService.getUidMapList(userIdList);
        // 定义格式化时间对象
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 循环拼接返回对象
        List<ArraignExcelVo> voList = CollUtil.newArrayList();
        for (EbDividendArraignEntity arraign : arraignList) {
            // 获取用户信息
            ArraignExcelVo vo = new ArraignExcelVo();
            vo.setAmountOfMoney(arraign.getAmountReceived().toString());
//            vo.setExamineAndApproveState(getExamineAndApproveState(arraign.getExamineAndApproveState()));
//            vo.setType(getArraignType(arraign.getType()));
//            vo.setBankName(arraign.getBankName());
            vo.setUserName((userMap != null && userMap.get(arraign.getUId()) != null) ? userMap.get(arraign.getUId()).getIdentityName() : "");
            vo.setBankCode(arraign.getBankCode());
//            vo.setCreatedTime(arraign.getCreatedTime() != null ? arraign.getCreatedTime().format(formatter) : "");
//            vo.setArraignTime(arraign.getArraignTime() != null ? arraign.getArraignTime().format(formatter) : "");
//            vo.setCreatedBy(arraign.getCreatedBy());
//            vo.setRemarks(arraign.getRemarks());
            vo.setRemarks("提现");
            voList.add(vo);
        }
        return voList;
    }

    private String getExamineAndApproveState(Integer type) {
        String typeStr = "";
        switch (type) {
            case 0:
                typeStr = "未审核";
                break;
            case 1:
                typeStr = "拒绝提现";
                break;
            case 2:
                typeStr = "审核通过";
                break;
            case 3:
                typeStr = "已到账";
                break;
        }
        return typeStr;
    }
    private String getArraignType(Integer type) {
        String typeStr = "";
        switch (type) {
            case 1:
                typeStr = "支付宝";
                break;
            case 2:
                typeStr = "银行卡(银联)";
                break;
        }
        return typeStr;
    }
}
